
package com.lz.config;

import java.util.*;
import java.util.concurrent.*;
import java.util.stream.*;
import com.lz.common.anno.aop.AspactCommonsum;
import com.lz.config.dal.entity.MethodLog;
import com.lz.config.dal.service.MethodLogService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
//实现BEan生命周期，当容器销毁时候调用destroy方法
public class Asp implements DisposableBean {

    private static final Logger log = LoggerFactory.getLogger(Asp.class);

    @Resource
    private MethodLogService methodLogService;

    @Override
    public void destroy() throws Exception {
        log.info("开始保存日志");

        // 需要更新的数据列表
        List<MethodLog> updateList = new ArrayList<>();
        List<MethodLog> insertList = new ArrayList<>();

        // 获取程序运行期间的方法调用统计
        Map<MethodLog, Integer> map = AspactCommonsum.getMap();

        // 获取数据库中已有的方法调用统计
        List<MethodLog> dbMethodLogs = methodLogService.list();
        ConcurrentHashMap<MethodLog, Integer> dbMethodLogMap =
                dbMethodLogs.stream()
                        .collect(Collectors.toConcurrentMap(
                                methodLog -> methodLog,
                                MethodLog::getNum,
                                (existing, replacement) -> existing,
                                ConcurrentHashMap::new
                        ));

        // 处理所有需要保存的方法调用统计
        map.forEach((programMethodLog, count) -> {
            // 查找数据库中是否存在相同的MethodLog
            MethodLog dbMethodLog = dbMethodLogs.stream()
                    .filter(log -> log.getMethodName().equals(programMethodLog.getMethodName())
                            && log.getCallerMethodName().equals(programMethodLog.getCallerMethodName()))
                    .findFirst()
                    .orElse(null);

            if (dbMethodLog != null) {
                // 如果数据库中已存在该记录，则更新
                dbMethodLog.setNum(dbMethodLog.getNum() + count);
                updateList.add(dbMethodLog);
            } else {
                // 如果数据库中不存在该记录，则新增
                MethodLog newMethodLog = new MethodLog();
                newMethodLog.setMethodName(programMethodLog.getMethodName());
                newMethodLog.setCallerMethodName(programMethodLog.getCallerMethodName());
                newMethodLog.setNum(count);
                insertList.add(newMethodLog);
            }
        });

        // 批量保存到数据库
        if (!insertList.isEmpty()) {
            methodLogService.saveBatch(insertList);
        }

        if (!updateList.isEmpty()) {
            methodLogService.updateBatchById(updateList);
        }

        log.info("日志保存完成");
    }

}